package blaha.genalg.graphgen;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

import org.apache.log4j.Logger;

import blaha.genalg.beans.Board;
import blaha.genalg.methods.CountDistance;
import blaha.genalg.methods.ReadAllProperties;
import blaha.genalg.staticmethods.Combination;
import blaha.logging.Log;

/**
 * Class for joining nodes with lots of connections with second level connections
 * 
 * @author pblaha
 * 
 */
public class JoinToCreateSecondLevel {

	private static final Logger log = Log.getLoggerMoje();

	/**
	 * Joins nodes by second level connections(trains, planes, etcetera)
	 * 
	 * @param settings
	 *            user input, how second level should be created
	 * @param board
	 *            represents board, where everything is done
	 * @return board with created second level connections
	 */
	public Board JoinSecondLevel(Board board, ReadAllProperties settings) {

		// second level connections
		// choose two points having
		List<Integer> lp = new ArrayList<Integer>();
		for (int o = 0; o < board.getPoints(); o++)
			if (board.getAllConnectionsOfNodeFromMatrixOfJoins(o) > settings.minConnectionsToBeSuitable)
				lp.add(o);

		//log.debug("Points to join are: " + lp.size());

		//for less than 2 points no:)
		if ((lp.size() < 2)) {
			settings.SLconnectionsOnBoard = 0;
				log.warn("There is 1 or 0 point to be joined to SL connection, skipping...");
				return board;
		}
		
		if(!settings.SLconnectionListenToConnectionnumber){
			 settings.SLconnectionsOnBoard = Combination.comb(lp.size(), 2);
		}
		// enought attempt, or second level points group too small
		if ((settings.SLconnectionsOnBoard > Combination.comb(lp.size(), 2))&&(settings.SLconnectionListenToConnectionnumber)) {
			settings.SLconnectionsOnBoard = Combination.comb(lp.size(), 2);
			log.warn("User settings invalid! Too many SLconnections set, new value will be: "
					+ settings.SLconnectionsOnBoard);
		}

		Random random = new Random(new Date().getTime());
		for (int y = 0; y < settings.SLconnectionsOnBoard; y++) {
			//probability to skip generation of SL edges
			if(!settings.SLconnectionListenToConnectionnumber)
			if(random.nextFloat()>settings.SLConnectionSuccess)
				continue;
			
			//log.debug("Count is " + countt + "  and C number is" + Combination.comb(lp.size(), 2));

			
			int firstPoint = 0;
			int secondPoint = 0;

			do {
				do {
					firstPoint = random.nextInt(lp.size());
					secondPoint = random.nextInt(lp.size());
					// half matrix
				} while (firstPoint <= secondPoint);
				//real points
				firstPoint = lp.get(firstPoint);
				secondPoint = lp.get(secondPoint);
			} while (Board.matrixOfJoins[firstPoint][secondPoint].isSLConnected());
			//log.debug("first point=" + firstPoint + "  second=" + secondPoint);
			Board.matrixOfJoins[firstPoint][secondPoint].setSLConnected(true);
			float pom = CountDistance.betweenTwoPoints(Board.map.get(firstPoint), Board.map.get(secondPoint));
			Board.matrixOfJoins[firstPoint][secondPoint].setSLDistance(pom);

			// 0 doesn't fit
			float num = 0;
			do {
				num = random.nextFloat();
			} while (num == 0);

			float dist = Board.matrixOfJoins[firstPoint][secondPoint].getSLDistance();
			Board.matrixOfJoins[firstPoint][secondPoint].SLweigth = dist * num;

		}

		return board;

	}

}
